//
//  AppDelegate.m
//  SampleClientApp
//
//  Created by Eberhard Rensch on 01.10.08.
//  Copyright 2008 Pleasant Software. All rights reserved.
//
// Plugin for iMedia Browser
//
// iMedia Browser is based on code originally developed by Jason Terhorst,
// further developed for Sandvox by Greg Hulands, Dan Wood, and Terrence Talbot.
// Contributions have also been made by Matt Gough, Martin Wennerberg and others
// as indicated in source files.
// 
// The iMedia Browser Framework is licensed under the following terms:
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in all or substantial portions of the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the following
// conditions:
// 
//	Redistributions of source code must retain the original terms stated here,
//	including this list of conditions, the disclaimer noted below, and the
//	following copyright notice: Copyright (c) 2008 by Pleasant Software
// 
//	Redistributions in binary form must include, in an end-user-visible manner,
//	e.g., About window, Acknowledgments window, or similar, the original
//	terms stated here, including this list of conditions, the disclaimer noted
//	below, and the aforementioned copyright notice.
// 
//	Neither the name of Pleasant Software, nor the names of
//	contributors to iMedia Browser may be used to endorse or promote products
//	derived from the Software without prior and express written permission from
//	Pleasant Software or individual contributors, as appropriate.
// 
// Disclaimer: THE SOFTWARE IS PROVIDED BY THE COPYRIGHT OWNER AND CONTRIBUTORS
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH, THE
// SOFTWARE OR THE USE OF, OR OTHER DEALINGS IN, THE SOFTWARE.
//


#import "AppDelegate.h"
#import <iMediaBrowser/iMedia.h>
#import "iMBiPhoneView.h"


@implementation AppDelegate
+ (void)initialize	// preferred over +load in most cases
{
	[iMediaBrowser registerBrowser:NSClassFromString(@"iMBiPhoneView")];
}

- (void)dealloc
{
    [iPhoneView release];

    [super dealloc];
}

- (void)awakeFromNib
{
    iPhoneView = [[iMBiPhoneView alloc] initWithFrame:[iPhoneContainerView bounds]];
	 [iPhoneView setIPhoneViewDelegate:self];
	 [iPhoneView setServiceType:@"imediasample"]; // Must match with server app!
	 
    [iPhoneContainerView addSubview:(NSView *)iPhoneView];
    
    [(NSView *)iPhoneView setAutoresizingMask:(NSViewHeightSizable|NSViewWidthSizable)];
    
    [iPhoneView willActivate];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
	[iMediaConfiguration sharedConfigurationWithDelegate:self];
}

- (void)windowWillClose:(NSNotification *)aNotification
{
    [iPhoneView didDeactivate];
}

- (BOOL)iMediaConfiguration:(iMediaConfiguration *)configuration willUseMediaParser:(NSString *)parserClassname forMediaType:(NSString *)media;
{
	return YES;
}

- (BOOL)hasAuthenticatedConnection
{
	return [(iMBiPhoneView*)iPhoneView hasAuthenticatedConnection];
}

#pragma mark iMBiPhoneView delegate methods

- (void)iPhoneViewStateChanged:(iMBiPhoneView*)view
{
	[self willChangeValueForKey:@"hasAuthenticatedConnection"];
	if([view hasAuthenticatedConnection])
	{
		[statusText setStringValue:NSLocalizedString(@"Connected",@"")];
		[progress setHidden:YES];
	}
	else
		[statusText setStringValue:NSLocalizedString(@"(Re-) Launch server app on iPhone",@"")];
	[self didChangeValueForKey:@"hasAuthenticatedConnection"];
}

- (void)iPhoneViewBeginFetchingPromissedFiles:(iMBiPhoneView*)view numberOfFiles:(UInt32)numberOfFiles;
{
	[statusText setStringValue:@""];
	[progress setMinValue:0];
	[progress setMaxValue:(double)numberOfFiles];
	[progress setDoubleValue:0.];
	[progress setHidden:NO];
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];
}

- (void)iPhoneViewEndFetchingPromissedFiles:(iMBiPhoneView*)view;
{
	[statusText setStringValue:NSLocalizedString(@"Connected",@"")];
	[progress setHidden:YES];
}

- (void)iPhoneViewBeginFetchingFile:(iMBiPhoneView*)view filePath:(NSString*)filePath;
{
	if(filePath)
	{
		[statusText setStringValue:[[NSFileManager defaultManager] displayNameAtPath:filePath]];
	}
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];
}

- (void)iPhoneViewEndFetchingFile:(iMBiPhoneView*)view
{
	[progress setDoubleValue:[progress doubleValue]+1.];
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];
}

- (void)iPhoneViewError:(iMBiPhoneView*)view message:(NSString*)message;
{				
	if(message==nil)
		message = NSLocalizedString(@"Unknown error",@"");
	[statusText setStringValue:NSLocalizedString(@"Error",@"")];
	[progress setHidden:YES];
	NSAlert* alert = [NSAlert alertWithMessageText:NSLocalizedString(@"BirdieConnect Error",@"") defaultButton:NSLocalizedString(@"OK",@"") alternateButton:nil otherButton:nil informativeTextWithFormat:message];
	[alert beginSheetModalForWindow:mainWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
	[sendFiles release];
	sendFiles=nil;
}

- (void)iPhoneViewSendFileSuccess:(iMBiPhoneView*)view;
{
	[sendFiles removeObjectAtIndex:0];
	if([sendFiles count]>0)
	{
		[statusText setStringValue:[[NSFileManager defaultManager] displayNameAtPath:[sendFiles objectAtIndex:0]]];
		[iPhoneView sendFile:[sendFiles objectAtIndex:0] uuid:nil destinationPath:nil dontWrap:NO overwriteExistingData:NO];
	}
	else
	{
		[statusText setStringValue:NSLocalizedString(@"Connected",@"")];
		[progress setHidden:YES];
		[sendFiles release];
		sendFiles=nil;
		[iPhoneView refreshCatalog];
	}
}

- (void)iPhoneViewSendFileAlreadyExists:(iMBiPhoneView*)view;
{
	NSString* message = [NSString stringWithFormat:NSLocalizedString(@"'%@' already exists on the device.",@""), [[NSFileManager defaultManager] displayNameAtPath:[sendFiles objectAtIndex:0]]];
	NSAlert* alert = [NSAlert alertWithMessageText:NSLocalizedString(@"File already exists",@"") defaultButton:NSLocalizedString(@"Cancel",@"") alternateButton:NSLocalizedString(@"Overwrite",@"") otherButton:nil informativeTextWithFormat:message];
	[alert beginSheetModalForWindow:mainWindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil];
}

- (void) alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
	if(returnCode==NSAlertDefaultReturn)
	{
		[statusText setStringValue:NSLocalizedString(@"Connected",@"")];
		[progress setHidden:YES];
		[sendFiles release];
		sendFiles=nil;
	}
	else
	{
		[iPhoneView sendFile:[sendFiles objectAtIndex:0] uuid:nil destinationPath:nil dontWrap:NO overwriteExistingData:YES];
	}
}

#pragma mark Sending Data & Files

- (void)sendFiles:(NSMutableArray*)files
{
	NSLog([files description]);
	sendFiles = [files retain];
	[statusText setStringValue:[[NSFileManager defaultManager] displayNameAtPath:[sendFiles objectAtIndex:0]]];
	[iPhoneView sendFile:[sendFiles objectAtIndex:0] uuid:nil destinationPath:nil dontWrap:NO overwriteExistingData:NO];
}

@end

@implementation FileDropper
- (void)awakeFromNib
{
	[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];

}

- (void)setImage:(NSImage*)image
{
	// Avoid changing of image
}

- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender
{
	NSDragOperation back = NSDragOperationNone;
   NSPasteboard *paste = [sender draggingPasteboard]; //gets the dragging-specific pasteboard from the sender
   NSArray *types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil]; //a list of types that we can accept
   NSString *desiredType = [paste availableTypeFromArray:types];
   if(desiredType!=nil && [appDelegate hasAuthenticatedConnection])
   {
      NSData *carriedData = [paste dataForType:desiredType];
      if( carriedData != nil )
      {
			if ([desiredType isEqualToString:NSFilenamesPboardType])
			{
            NSArray *fileArray = [paste propertyListForType:NSFilenamesPboardType];
				NSEnumerator* fileEnum = [fileArray objectEnumerator];
				NSString* filename;
				while(filename = [fileEnum nextObject])
				{
					back = NSDragOperationCopy;
					break;
				}
			}
		}
	}
	return back;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
	BOOL back=NO;
	
	NSMutableArray* draggedFiles = [NSMutableArray array];
   NSPasteboard *paste = [sender draggingPasteboard]; //gets the dragging-specific pasteboard from the sender
   NSArray *types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil]; //a list of types that we can accept
   NSString *desiredType = [paste availableTypeFromArray:types];
   if(desiredType!=nil && [appDelegate hasAuthenticatedConnection])
   {
      NSData *carriedData = [paste dataForType:desiredType];
      if( carriedData != nil )
      {
			if ([desiredType isEqualToString:NSFilenamesPboardType])
			{
            NSArray *fileArray = [paste propertyListForType:NSFilenamesPboardType];
				NSEnumerator* fileEnum = [fileArray objectEnumerator];
				NSString* filename;
				while(filename = [fileEnum nextObject])
				{
					back=YES;
					[draggedFiles addObject:filename];
				}
			}
		}
	}
	
	if(back)
		[appDelegate performSelector:@selector(sendFiles:) withObject:draggedFiles afterDelay:0.];
		
	return back;
}
@end

@implementation EmbeddedTextDropper
- (void)awakeFromNib
{
	[self registerForDraggedTypes:[NSArray arrayWithObject:iMBNativePasteboardFlavor]];

}

- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender
{
	NSDragOperation back = NSDragOperationNone;
   NSPasteboard *paste = [sender draggingPasteboard]; //gets the dragging-specific pasteboard from the sender
   NSArray *types = [NSArray arrayWithObjects: iMBNativePasteboardFlavor, nil]; //a list of types that we can accept
   NSString *desiredType = [paste availableTypeFromArray:types];
   if(desiredType!=nil)
   {
		NSDictionary *native = [NSUnarchiver unarchiveObjectWithData:[paste dataForType:iMBNativePasteboardFlavor]];
		if([[native objectForKey:iMBControllerClassName] isEqualToString:@"iMBiPhoneView"])
		{
			NSArray* draggedNativeData = [native objectForKey:@"iMBNativeDataArray"];
			if([draggedNativeData count]==1 && [[draggedNativeData lastObject] objectForKey:@"embeddedData"]!=nil)
				back = NSDragOperationCopy;
		}
	}
	return back;
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
	BOOL back=NO;
	
	NSPasteboard *paste = [sender draggingPasteboard]; //gets the dragging-specific pasteboard from the sender
   NSArray *types = [NSArray arrayWithObjects: iMBNativePasteboardFlavor, nil]; //a list of types that we can accept
   NSString *desiredType = [paste availableTypeFromArray:types];
   if(desiredType!=nil)
   {
		NSDictionary *native = [NSUnarchiver unarchiveObjectWithData:[paste dataForType:iMBNativePasteboardFlavor]];
		if([[native objectForKey:iMBControllerClassName] isEqualToString:@"iMBiPhoneView"])
		{
			NSArray* draggedNativeData = [native objectForKey:@"iMBNativeDataArray"];
			if([draggedNativeData count]==1)
			{
				NSString* embeddedText = [[NSString alloc] initWithData:[[draggedNativeData lastObject] objectForKey:@"embeddedData"] encoding:NSUTF8StringEncoding];
				[textField setStringValue:embeddedText];
				[embeddedText release];
				back = YES;
			}
		}
	}
			
	return back;
}
@end

